import { GameObject } from "./GameObject";
import { Snake } from "./Snake";
import { Wall } from "./Wall";
/* 
存在的问题：当13*13的地图的环境下，左上角和右小角的蛇可能会走到一起去，所以将地图修改为13*14且地图改为中心对称格式


*/

export class GameMap extends GameObject{
    constructor(ctx,parent,store){
        super(); //父类的构造函数
        this.ctx=ctx; //canvas画笔
        this.parent=parent; 
        this.store = store;
        this.L=0;//一个格的绝对距离
        this.rows=13; //行数
        this.cols=14; //列数
        this.walls=[];//用于保存障碍物
        this.innerWallsCount = 10;//定义内部障碍物数量
        //实例化蛇
        this.snakes=[
            new Snake({id:0,color:"#4876EC",r:this.rows-2,c:1},this),
            new Snake({id:1,color:"#F94848",r:1,c:this.cols-2},this),
        ];
       
    }
    //判断地图联通性
    //参考题目:蛇形矩阵
    checkConnectivity(g, sx, sy, tx, ty){
        //递归深度优先搜索
        //sx sy tx ty 分别为起点终点的横纵坐标
        if (sx == tx && sy == ty) return true; /* 如果起点和终点的坐标相同则证明有连通性 */
        g[sx][sy] = true; /* 将起点设置为可到达 */
        /* 枚举四个相邻方向的点 */
        let dx = [-1, 0, 1, 0];
        let dy = [0, 1, 0, -1];
        for(let i = 0; i < 4; i++){
            let x = sx + dx[i];
            let y = sy + dy[i];
            /* 如果可以到达相邻的点并且相邻的点到终点是联通的，则证明有连通性 */
            if(!g[x][y] && this.checkConnectivity(g, x, y, tx, ty))
                return true;
        }
        //否则没有连通性
        return false;
    }
    //创建障碍物
    createWalls(){
        //直接将地图取来 -- 从后端传过来
        const g = this.store.state.pk.gamemap;
        //创建障碍物对象，并添加到this.walls数组
        for( let r = 0; r<this.rows;r++){
            for( let c = 0; c < this.cols ; c++){
                if(g[r][c]){
                    this.walls.push(new Wall(r,c,this));
                }
            }
        }
       
    }

    //监听事件
    addListeningEvents(){
        console.log(this.store.state.record.is_record);
        if (this.store.state.record.is_record) {
            let k = 0;

            const a_steps = this.store.state.record.a_steps;
            const b_steps = this.store.state.record.b_steps;
            const loser = this.store.state.record.record_loser;
            const [snake0, snake1] = this.snakes;
            const interval_id = setInterval(() => {
                if (k >= a_steps.length - 1) {
                    if (loser === "all" || loser === "A") {
                        snake0.status = "die";
                    }
                    if (loser === "all" || loser === "B") {
                        snake1.status = "die";
                    }
                    clearInterval(interval_id);
                } else {
                    snake0.setDirection(parseInt(a_steps[k]));
                    snake1.setDirection(parseInt(b_steps[k]));
                }
                k ++ ;
            }, 300);
        }else{
            this.ctx.canvas.focus();//聚焦
            //const [snake0,snake1] =this.snakes;
            this.ctx.canvas.addEventListener("keydown",e=>{
            //wasd控制移动
            let d = -1;
            if(e.key === 'w') d = 0;
            else if (e.key === 'd') d = 1;
            else if (e.key === 's') d = 2;
            else if (e.key === 'a') d = 3;

            if(d >= 0) {
                //有效输入
                this.store.state.pk.socket.send(JSON.stringify({
                    event:"move",
                    direction:d,
                }))
            }
        });
        }


        

    }
    start(){
        this.createWalls();
        this.addListeningEvents();
    }
    //更新地图大小
    updateSize(){
        this.L = parseInt(Math.min(this.parent.clientWidth / this.cols, this.parent.clientHeight / this.rows));
        this.ctx.canvas.width=this.L*this.cols;
        this.ctx.canvas.height=this.L*this.rows;
    }
    checkReady(){ //判断两条蛇是否都已经准备好了
        for(const snake of this.snakes){
            if(snake.status!=="idle") {
                return false ;
                }
            if(snake.direction === -1){
                return false ;
            } 
        }
        return true;
    }
    nextStep(){
        for(const snake of this.snakes){
            snake.nextStep();
        }
    }
    //每帧执行一次
    update(){
        //正方形大小 自适应变化
        this.updateSize();
        //判断蛇的下一步
        if(this.checkReady()){
            this.nextStep(); //准备好了就走下一步
        }
        this.render();
    }
    render(){ //渲染
        const colorEven = '#AAD751'//偶数颜色
        const colorOdd = '#A2D149'//奇数颜色
        for(let r = 0 ; r < this.rows; r++){
            for(let c = 0; c < this.cols; c++){
                if(( r + c ) % 2 == 0){
                    this.ctx.fillStyle = colorEven;
                }else{
                    this.ctx.fillStyle = colorOdd;
                }
                this.ctx.fillRect(c* this.L, r* this.L, this.L, this.L);
            }
        }    
    }
    checkValid(cell){ //合法性判断
        for(const wall of this.walls){
            if(wall.r === cell.r &&wall.c === cell.c){
                return false;
            }
        }
        for(const snake of this.snakes){
            let k=snake.cells.length;
            if(!snake.checkTailIncreasing()){ //蛇的长度不增加 也就是蛇尾会前进，此时不做判断
                k--; //也就是不在snake.cells[k]在这个位置上做判断 k-1

            }
            //新增的cell与每条蛇的每个cell逐个判断
            for(let i=0;i<k;i++){
                if(snake.cells[i].r===cell.r && snake.cells[i].c === cell.c){
                    return false;
                }
            }
        }
        return true;

    }
}